package kevin.hbase.service;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import kevin.hbase.mapper.ObdVersionHistoryMapper;
import kevin.hbase.mapper.UnitMapper;
import kevin.hbase.util.DateTimeUtil;
import kevin.hbase.util.EmailUtil;
import kevin.hbase.util.HBaseKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class DeviceService {
    @Autowired
    private ObdVersionHistoryMapper obdVersionHistoryMapper;

    @Autowired
    private UnitMapper unitMapper;

    @Autowired
    private Connection hbaseConnection;

    @Value("${mail.to}")
    private String mailTo;

    @Value("${task.versionReport.saveDir}")
    private String saveDir;

    @Value("${task.delGps.agencyPaths}")
    private String delGpsAgencyPaths;

    @Value("${task.delGps.startTime}")
    private String delGpsStartTime;

    @Value("${task.delGps.endTime}")
    private String delGpsEndTime;

    @Value("${task.delGps.batchDays}")
    private Integer delGpsBatchDays;

    public void sendVersionReport() {
        Map<String, Object> params = new HashMap<>();
        String yesterday = DateTimeUtil.getYesterday();
        params.put("startTime", yesterday + " 00:00:00");
        params.put("endTime", yesterday + " 23:59:59");
        List<Map<String, Object>> list = obdVersionHistoryMapper.selectVersionStatictis(params);
        if (list == null || list.size() == 0) {
            log.info("sendVersionReport is null or size is 0,params:{}", params);
            return;
        }
        String file = "versionReport_" + yesterday + ".xlsx";
        String subject = yesterday + "_终端重启次数分析报告";
        String savePath = saveDir + file;
        File report = new File(savePath);
        if (report.exists()) {
            report.delete();
        }
        List<Map<String, Object>> rows = new ArrayList<>();
        try {
            for (Map<String, Object> map : list) {
                Map<String, Object> row = new LinkedHashMap();
                row.put("设备号", map.get("deviceId"));
                row.put("上报次数", map.get("deliverCount"));
                rows.add(row);
            }
            ExcelWriter writer = ExcelUtil.getWriter(report);
            writer.write(rows, true);
            writer.close();

            log.info("report create finished,path:{}", savePath);
            EmailUtil.sendMail(mailTo, subject, subject + ",请查收！", savePath, file);
            log.info("sendVersionReport finished,report:{}", savePath);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public List<Map<String, Object>> getDelGpsDeviceList() {
        List<String> list = Arrays.asList(delGpsAgencyPaths.split(";"));
        return unitMapper.getDelGpsDeviceList(list);
    }

    public void delGps(List<Map<String, Object>> list, int index) throws Exception {
        for (Map<String, Object> map : list) {
            Table table = hbaseConnection.getTable(TableName.valueOf("t_history"));
            String deviceId = (String) map.get("deviceId");
            LocalDateTime start = DateTimeUtil.parseStringToDateTime(delGpsStartTime, DateTimeUtil.DATETIME_FORMAT);
            LocalDateTime end = DateTimeUtil.parseStringToDateTime(delGpsEndTime, DateTimeUtil.DATETIME_FORMAT);
            LocalDateTime startDateTime = start;
            LocalDateTime endDateTime;
            int total = 0;
            for (; ; ) {
                endDateTime = startDateTime.plusDays(delGpsBatchDays);
                long startL = DateTimeUtil.getTimestampOfDateTimeGMT8(startDateTime);
                long endL = DateTimeUtil.getTimestampOfDateTimeGMT8(endDateTime);
                byte[] startKey = HBaseKeyUtil.getKey(deviceId, startL);
                byte[] endKey = HBaseKeyUtil.getKey(deviceId, endL);
                Scan scan = new Scan(startKey, endKey);
                ResultScanner rsscan = table.getScanner(scan);
                scan.setCaching(2);
                scan.setReversed(true);
                List<Delete> deleteList = new ArrayList<>();
                Iterator<Result> iter = rsscan.iterator();
                while (iter.hasNext()) {
                    Result rs = iter.next();
                    deleteList.add(new Delete(rs.getRow()));
                }
                int size = deleteList.size();
                if (size > 0) {
                    table.delete(deleteList);
                    log.debug("DelGpsHandler:{},del info,callLetter:{},start:{},end:{},size:{}", index, deviceId, DateTimeUtil.getDateTimeGMT8AsString(startL, DateTimeUtil.DATETIME_FORMAT), DateTimeUtil.getDateTimeGMT8AsString(endL, DateTimeUtil.DATETIME_FORMAT), size);
                    total += size;
                }
                rsscan.close();
                startDateTime = endDateTime;
                if (endDateTime.isAfter(end)) {
                    break;
                }
            }
            log.info("DelGpsHandler:{},callLetter;{},del gps num:{}", index, deviceId, total);
            table.close();
        }
    }
}
